Dummy App for Project investigation on Collaborative M-learning So far downloadable on Blackberry, Android, Windows, Nokia,Symbian devices.......

Application is meant to help teams collaborate in a working environment, having a data storage, vcs, facebook, google hangout and a file upload feature

Web/Mobile Hybrid Site in Development

What we are trying to Achieve 6025 { /** * Created by user on 01/07/2016. */ /** * @license OpenTok.js v2.8.0 14c8b62 HEAD * * Copyright (c) 2010-2016 TokBox, Inc. * Subject to the applicable Software Development Kit (SDK) License Agreement: * https://tokbox.com/support/sdk_license * * Date: April 17 18:37:35 2016 */ (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o>> ((i & 0x03) << 3) & 0xff; } return _rnds; }; } module.exports = rng; }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) },{}],3:[function(require,module,exports){ // uuid.js // // Copyright (c) 2010-2012 Robert Kieffer // MIT License - http://opensource.org/licenses/mit-license.php // Unique ID creation requires a high quality random # generator. We feature // detect to determine the best RNG source, normalizing to a function that // returns 128-bits of randomness, since that's what's usually required var _rng = require('./rng'); // Buffer class to use, // we can't use `Buffer || Array` otherwise Buffer would be // shimmed by browserify and added to the browser build var BufferClass = require('./buffer'); // Maps for number <-> hex string conversion var _byteToHex = []; var _hexToByte = {}; for (var i = 0; i < 256; i++) { _byteToHex[i] = (i + 0x100).toString(16).substr(1); _hexToByte[_byteToHex[i]] = i; } // **`parse()` - Parse a UUID into it's component bytes** function parse(s, buf, offset) { var i = (buf && offset) || 0, ii = 0; buf = buf || []; s.toLowerCase().replace(/[0-9a-f]{2}/g, function(oct) { if (ii < 16) { // Don't overflow! buf[i + ii++] = _hexToByte[oct]; } }); // Zero out remaining bytes if string was short while (ii < 16) { buf[i + ii++] = 0; } return buf; } // **`unparse()` - Convert UUID byte array (ala parse()) into a string** function unparse(buf, offset) { var i = offset || 0, bth = _byteToHex; return bth[buf[i++]] + bth[buf[i++]] + bth[buf[i++]] + bth[buf[i++]] + '-' + bth[buf[i++]] + bth[buf[i++]] + '-' + bth[buf[i++]] + bth[buf[i++]] + '-' + bth[buf[i++]] + bth[buf[i++]] + '-' + bth[buf[i++]] + bth[buf[i++]] + bth[buf[i++]] + bth[buf[i++]] + bth[buf[i++]] + bth[buf[i++]]; } // **`v1()` - Generate time-based UUID** // // Inspired by https://github.com/LiosK/UUID.js // and http://docs.python.org/library/uuid.html // random #'s we need to init node and clockseq var _seedBytes = _rng(); // Per 4.5, create and 48-bit node id, (47 random bits + multicast bit = 1) var _nodeId = [ _seedBytes[0] | 0x01, _seedBytes[1], _seedBytes[2], _seedBytes[3], _seedBytes[4], _seedBytes[5] ]; // Per 4.2.2, randomize (14 bit) clockseq var _clockseq = (_seedBytes[6] << 8 | _seedBytes[7]) & 0x3fff; // Previous uuid creation time var _lastMSecs = 0, _lastNSecs = 0; // See https://github.com/broofa/node-uuid for API details function v1(options, buf, offset) { var i = buf && offset || 0; var b = buf || []; options = options || {}; var clockseq = options.clockseq !== undefined ? options.clockseq : _clockseq; // UUID timestamps are 100 nano-second units since the Gregorian epoch, // (1582-10-15 00:00). JSNumbers aren't precise enough for this, so // time is handled internally as 'msecs' (integer milliseconds) and 'nsecs' // (100-nanoseconds offset from msecs) since unix epoch, 1970-01-01 00:00. var msecs = options.msecs !== undefined ? options.msecs : new Date().getTime(); // Per 4.2.1.2, use count of uuid's generated during the current clock // cycle to simulate higher resolution clock var nsecs = options.nsecs !== undefined ? options.nsecs : _lastNSecs + 1; // Time since last uuid creation (in msecs) var dt = (msecs - _lastMSecs) + (nsecs - _lastNSecs)/10000; // Per 4.2.1.2, Bump clockseq on clock regression if (dt < 0 && options.clockseq === undefined) { clockseq = clockseq + 1 & 0x3fff; } // Reset nsecs if clock regresses (new clockseq) or we've moved onto a new // time interval if ((dt < 0 || msecs > _lastMSecs) && options.nsecs === undefined) { nsecs = 0; } // Per 4.2.1.2 Throw error if too many uuids are requested if (nsecs >= 10000) { throw new Error('uuid.v1(): Can\'t create more than 10M uuids/sec'); } _lastMSecs = msecs; _lastNSecs = nsecs; _clockseq = clockseq; // Per 4.1.4 - Convert from unix epoch to Gregorian epoch msecs += 12219292800000; // `time_low` var tl = ((msecs & 0xfffffff) * 10000 + nsecs) % 0x100000000; b[i++] = tl >>> 24 & 0xff; b[i++] = tl >>> 16 & 0xff; b[i++] = tl >>> 8 & 0xff; b[i++] = tl & 0xff; // `time_mid` var tmh = (msecs / 0x100000000 * 10000) & 0xfffffff; b[i++] = tmh >>> 8 & 0xff; b[i++] = tmh & 0xff; // `time_high_and_version` b[i++] = tmh >>> 24 & 0xf | 0x10; // include version b[i++] = tmh >>> 16 & 0xff; // `clock_seq_hi_and_reserved` (Per 4.2.2 - include variant) b[i++] = clockseq >>> 8 | 0x80; // `clock_seq_low` b[i++] = clockseq & 0xff; // `node` var node = options.node || _nodeId; for (var n = 0; n < 6; n++) { b[i + n] = node[n]; } return buf ? buf : unparse(b); } // **`v4()` - Generate random UUID** // See https://github.com/broofa/node-uuid for API details function v4(options, buf, offset) { // Deprecated - 'format' argument, as supported in v1.2 var i = buf && offset || 0; if (typeof(options) == 'string') { buf = options == 'binary' ? new BufferClass(16) : null; options = null; } options = options || {}; var rnds = options.random || (options.rng || _rng)(); // Per 4.4, set bits for version and `clock_seq_hi_and_reserved` rnds[6] = (rnds[6] & 0x0f) | 0x40; rnds[8] = (rnds[8] & 0x3f) | 0x80; // Copy bytes to buffer, if provided if (buf) { for (var ii = 0; ii < 16; ii++) { buf[i + ii] = rnds[ii]; } } return buf || unparse(rnds); } // Export public API var uuid = v4; uuid.v1 = v1; uuid.v4 = v4; uuid.parse = parse; uuid.unparse = unparse; uuid.BufferClass = BufferClass; module.exports = uuid; },{"./buffer":1,"./rng":2}],4:[function(require,module,exports){ (function (global){ 'use strict'; // The top-level namespace, also performs basic DOMElement selecting. // // @example Get the DOM element with the id of 'domId' // OTHelpers('#domId') // // @example Get all video elements // OTHelpers('video') // // @example Get all elements with the class name of 'foo' // OTHelpers('.foo') // // @example Get all elements with the class name of 'foo', // and do something with the first. // var collection = OTHelpers('.foo'); // console.log(collection.first); // // // The second argument is the context, that is document or parent Element, to // select from. // // @example Get a video element within the element with the id of 'domId' // OTHelpers('video', OTHelpers('#domId')) // // // // OTHelpers will accept any of the following and return a collection: // OTHelpers() // OTHelpers('css selector', optionalParentNode) // OTHelpers(DomNode) // OTHelpers([array of DomNode]) // // The collection is a ElementCollection object, see the ElementCollection docs for usage info. // var OTHelpers = require('./elementCollection/shorthandSelector'); OTHelpers.ElementCollection = require('./elementCollection/index'); OTHelpers.util = require('./util'); OTHelpers.env = require('./env'); OTHelpers.logging = require('./logging'); OTHelpers.ajax = require('./ajax'); OTHelpers.callbacks = require('./callbacks'); OTHelpers.Event = require('./behaviours/eventing/event'); OTHelpers.eventing = require('./behaviours/eventing'); OTHelpers.statable = require('./behaviours/statable'); OTHelpers.Analytics = require('./analytics'); OTHelpers.requestAnimationFrame = require('./requestAnimationFrame'); OTHelpers.async = require('../vendor/async'); OTHelpers.capabilities = require('./capabilities'); OTHelpers.casting = require('./casting'); OTHelpers.Collection = require('./collection'); OTHelpers.cookies = require('./cookies'); OTHelpers.domExtras = require('./domExtras'); OTHelpers.domLoad = require('./domLoad'); OTHelpers.Error = require('./error'); OTHelpers.Modal = require('./modal'); OTHelpers.isWebSocketSupported = require('./isWebSocketSupported'); OTHelpers.useLogHelpers = require('./logging/mixin'); // TODO: Remove the need for this kind of bazzadry. for (var key in OTHelpers) { var component = OTHelpers[key]; var attachments = component._attachToOTHelpers; if (attachments) { for (var attachmentName in attachments) { if (Object.hasOwnProperty.call(OTHelpers, attachmentName) && !(key === 'util' && attachmentName === 'bind')) { console.warn( 'More than one module is trying to define ' + attachmentName + ' on OTHelpers.' ); } OTHelpers[attachmentName] = attachments[attachmentName]; } } } var previousOTHelpers = global.OTHelpers; OTHelpers.noConflict = function() { OTHelpers.noConflict = function() { return OTHelpers; }; global.OTHelpers = previousOTHelpers; return OTHelpers; }; global.OTHelpers = OTHelpers; // A guard to detect when IE has performed cleans on unload global.___othelpers = true; module.exports = OTHelpers; }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) },{"../vendor/async":35,"./ajax":5,"./analytics":6,"./behaviours/eventing":7,"./behaviours/eventing/event":9,"./behaviours/statable":11,"./callbacks":12,"./capabilities":13,"./casting":14,"./collection":15,"./cookies":16,"./domExtras":17,"./domLoad":18,"./elementCollection/index":23,"./elementCollection/shorthandSelector":24,"./env":25,"./error":26,"./isWebSocketSupported":27,"./logging":29,"./logging/mixin":30,"./modal":32,"./requestAnimationFrame":33,"./util":34}],5:[function(require,module,exports){ 'use strict'; /* jshint browser:true, smarttabs:true */ var $ = require('../elementCollection/shorthandSelector'); var env = require('../env'); var makeEverythingAttachToOTHelpers = require('../makeEverythingAttachToOTHelpers'); var util = require('../util'); var browserAjax = {}; module.exports = browserAjax; function formatPostData(data) { //, contentType // If it's a string, we assume it's properly encoded if (typeof(data) === 'string') return data; var queryString = []; for (var key in data) { queryString.push( encodeURIComponent(key) + '=' + encodeURIComponent(data[key]) ); } return queryString.join('&').replace(/\+/g, '%20'); } if (env.name !== 'Node') { browserAjax.xdomainRequest = function(url, options, callback) { /* global XDomainRequest */ // TODO: this is deprecated: https://developer.mozilla.org/en-US/docs/Web/API/XDomainRequest var xdr = new XDomainRequest(), _options = options || {}, _method = _options.method.toLowerCase(); if(!_method) { callback(new Error('No HTTP method specified in options')); return; } _method = _method.toUpperCase(); if(!(_method === 'GET' || _method === 'POST')) { callback(new Error('HTTP method can only be ')); return; } function done(err, event) { xdr.onload = xdr.onerror = xdr.ontimeout = function() {}; xdr = void 0; callback(err, event); } xdr.onload = function() { done(null, { target: { responseText: xdr.responseText, headers: { 'content-type': xdr.contentType } } }); }; xdr.onerror = function() { done(new Error('XDomainRequest of ' + url + ' failed')); }; xdr.ontimeout = function() { done(new Error('XDomainRequest of ' + url + ' timed out')); }; xdr.open(_method, url); xdr.send(options.body && formatPostData(options.body)); }; browserAjax.request = function(url, options, callback) { var request = new XMLHttpRequest(), _options = options || {}, _method = _options.method; if(!_method) { callback(new Error('No HTTP method specified in options')); return; } if (options.overrideMimeType) { if (request.overrideMimeType) { request.overrideMimeType(options.overrideMimeType); } delete options.overrideMimeType; } // Setup callbacks to correctly respond to success and error callbacks. This includes // interpreting the responses HTTP status, which XmlHttpRequest seems to ignore // by default. if (callback) { $(request).on('load', function(event) { var status = event.target.status; // We need to detect things that XMLHttpRequest considers a success, // but we consider to be failures. if ( status >= 200 && (status < 300 || status === 304) ) { callback(null, event); } else { callback(event); } }); $(request).on('error', callback); } request.open(options.method, url, true); if (!_options.headers) _options.headers = {}; for (var name in _options.headers) { if (!Object.prototype.hasOwnProperty.call(_options.headers, name)) { continue; } request.setRequestHeader(name, _options.headers[name]); } request.send(options.body && formatPostData(options.body)); }; browserAjax.get = function(url, options, callback) { var _options = util.extend(options || {}, { method: 'GET' }); browserAjax.request(url, _options, callback); }; browserAjax.post = function(url, options, callback) { var _options = util.extend(options || {}, { method: 'POST' }); if(_options.xdomainrequest) { browserAjax.xdomainRequest(url, _options, callback); } else { browserAjax.request(url, _options, callback); } }; browserAjax.getJSON = function(url, options, callback) { options = options || {}; var done = function(error, event) { if(error) { callback(error, event && event.target && event.target.responseText); } else { var response; try { response = JSON.parse(event.target.responseText); } catch(e) { // Badly formed JSON callback(e, event && event.target && event.target.responseText); return; } callback(null, response, event); } }; if(options.xdomainrequest) { browserAjax.xdomainRequest(url, { method: 'GET' }, done); } else { var extendedHeaders = util.extend({ 'Accept': 'application/json' }, options.headers || {}); browserAjax.get(url, util.extend(options || {}, { headers: extendedHeaders }), done); } }; makeEverythingAttachToOTHelpers(browserAjax); } },{"../elementCollection/shorthandSelector":24,"../env":25,"../makeEverythingAttachToOTHelpers":31,"../util":34}],6:[function(require,module,exports){ 'use strict'; var ajax = require('./ajax'); var env = require('./env'); var logging = require('./logging'); var util = require('./util'); var uuid = require('uuid'); // Singleton interval var logQueue = [], queueRunning = false; module.exports = function Analytics(loggingUrl, debugFn) { var endPoint = loggingUrl + '/logging/ClientEvent', endPointQos = loggingUrl + '/logging/ClientQos', reportedErrors = {}, send = function(data, isQos, callback) { ajax.post((isQos ? endPointQos : endPoint) + '?_=' + uuid.v4(), { body: data, xdomainrequest: (env.name === 'IE' && env.version < 10), overrideMimeType: 'text/plain', headers: { 'Accept': 'text/plain', 'Content-Type': 'application/json' } }, callback); }, throttledPost = function() { // Throttle logs so that they only happen 1 at a time if (!queueRunning && logQueue.length > 0) { queueRunning = true; var curr = logQueue[0]; // Remove the current item and send the next log var processNextItem = function() { logQueue.shift(); queueRunning = false; throttledPost(); }; if (curr) { send(curr.data, curr.isQos, function(err) { if (err) { var debugMsg = 'Failed to send ClientEvent, moving on to the next item.'; if (debugFn) { debugFn(debugMsg); } else { console.log(debugMsg); } if (curr.onComplete) { curr.onComplete(); } // There was an error, move onto the next item } if (curr.onComplete) { curr.onComplete(err); } setTimeout(processNextItem, 50); }); } } }, post = function(data, onComplete, isQos) { logQueue.push({ data: data, onComplete: onComplete, isQos: isQos }); throttledPost(); }, shouldThrottleError = function(code, type, partnerId) { if (!partnerId) return false; var errKey = [partnerId, type, code].join('_'), //msgLimit = DynamicConfig.get('exceptionLogging', 'messageLimitPerPartner', partnerId); msgLimit = 100; if (msgLimit === null || msgLimit === undefined) return false; return (reportedErrors[errKey] || 0) <= msgLimit; }; // Log an error via ClientEvents. // // @param [String] code // @param [String] type // @param [String] message // @param [Hash] details additional error details // // @param [Hash] options the options to log the client event with. // @option options [String] action The name of the Event that we are logging. E.g. // 'TokShowLoaded'. Required. // @option options [String] variation Usually used for Split A/B testing, when you // have multiple variations of the +_action+. // @option options [String] payload The payload. Required. // @option options [String] sessionId The active OpenTok session, if there is one // @option options [String] connectionId The active OpenTok connectionId, if there is one // @option options [String] partnerId // @option options [String] guid ... // @option options [String] streamId ... // @option options [String] section ... // @option options [String] clientVersion ... // // Reports will be throttled to X reports (see exceptionLogging.messageLimitPerPartner // from the dynamic config for X) of each error type for each partner. Reports can be // disabled/enabled globally or on a per partner basis (per partner settings // take precedence) using exceptionLogging.enabled. // this.logError = function(code, type, message, details, options) { if (!options) options = {}; var partnerId = options.partnerId; if (shouldThrottleError(code, type, partnerId)) { //OT.log('ClientEvents.error has throttled an error of type ' + type + '.' + // code + ' for partner ' + (partnerId || 'No Partner Id')); return; } var errKey = [partnerId, type, code].join('_'), payload = details ? details : null; reportedErrors[errKey] = typeof(reportedErrors[errKey]) !== 'undefined' ? reportedErrors[errKey] + 1 : 1; this.logEvent(util.extend(options, { action: type + '.' + code, payload: payload }), false); }; // Log a client event to the analytics backend. // // @example Logs a client event called 'foo' // this.logEvent({ // action: 'foo', // payload: 'bar', // sessionId: sessionId, // connectionId: connectionId // }, false) // // @param [Hash] data the data to log the client event with. // @param [Boolean] qos Whether this is a QoS event. // @param [Boolean] throttle A number specifying the ratio of events to be sent // out of the total number of events (other events are not ignored). If not // set to a number, all events are sent. // @param [Number] completionHandler A completion handler function to call when the // client event POST request succeeds or fails. If it fails, an error // object is passed into the function. (See throttledPost().) // this.logEvent = function(data, qos, throttle, completionHandler) { if (!qos) qos = false; if (throttle && !isNaN(throttle)) { if (Math.random() > throttle) { logging.debug('skipping sending analytics due to throttle:', data); return; } } logging.debug('sending analytics:', data); // TODO: catch error when stringifying an object that has a circular reference data = JSON.stringify(data); post(data, completionHandler, qos); }; // Log a client QOS to the analytics backend. // Log a client QOS to the analytics backend. // @option options [String] action The name of the Event that we are logging. // E.g. 'TokShowLoaded'. Required. // @option options [String] variation Usually used for Split A/B testing, when // you have multiple variations of the +_action+. // @option options [String] payload The payload. Required. // @option options [String] sessionId The active OpenTok session, if there is one // @option options [String] connectionId The active OpenTok connectionId, if there is one // @option options [String] partnerId // @option options [String] guid ... // @option options [String] streamId ... // @option options [String] section ... // @option options [String] clientVersion ... // this.logQOS = function(options) { this.logEvent(options, true); }; }; },{"./ajax":5,"./env":25,"./logging":29,"./util":34,"uuid":3}],7:[function(require,module,exports){ 'use strict'; var browserEventing = require('./eventing/browser'); var logging = require('../logging'); var nodeEventing = require('./eventing/node'); var util = require('../util'); /** * This base class defines the on, once, and off * methods of objects that can dispatch events. * * @class EventDispatcher */ module.exports = function eventing(self, syncronous) { var innerEventing = (nodeEventing || browserEventing)(this, syncronous); /** * Adds an event handler function for one or more events. * *

* The following code adds an event handler for one event: *

* *
         * obj.on("eventName", function (event) {
  *     // This is the event handler.
  * });
         * 
* *

If you pass in multiple event names and a handler method, the handler is * registered for each of those events:

* *
         * obj.on("eventName1 eventName2",
         *        function (event) {
  *            // This is the event handler.
  *        });
         * 
* *

You can also pass in a third context parameter (which is optional) to * define the value of this in the handler method:

* *
obj.on("eventName",
         *        function (event) {
  *            // This is the event handler.
  *        },
         *        obj);
         * 
* *

* The method also supports an alternate syntax, in which the first parameter is an object * that is a hash map of event names and handler functions and the second parameter (optional) * is the context for this in each handler: *

*
         * obj.on(
         *    {
  *       eventName1: function (event) {
  *               // This is the handler for eventName1.
  *           },
  *       eventName2:  function (event) {
  *               // This is the handler for eventName2.
  *           }
  *    },
         *    obj);
         * 
* *

* If you do not add a handler for an event, the event is ignored locally. *

* * @param {String} type The string identifying the type of event. You can specify multiple event * names in this string, separating them with a space. The event handler will process each of * the events. * @param {Function} handler The handler function to process the event. This function takes * the event object as a parameter. * @param {Object} context (Optional) Defines the value of this in the event * handler function. * * @returns {EventDispatcher} The EventDispatcher object. * * @memberOf EventDispatcher * @method #on * @see off() * @see once() * @see Events */ self.on = function(eventNames, handlerOrContext, context) { if (typeof(eventNames) === 'string' && handlerOrContext) { innerEventing.addListeners(eventNames.split(' '), handlerOrContext, context); } else { for (var name in eventNames) { if (eventNames.hasOwnProperty(name)) { innerEventing.addListeners([name], eventNames[name], handlerOrContext); } } } return this; }; /** * Removes an event handler or handlers. * *

If you pass in one event name and a handler method, the handler is removed for that * event:

* *
obj.off("eventName", eventHandler);
* *

If you pass in multiple event names and a handler method, the handler is removed for * those events:

* *
obj.off("eventName1 eventName2", eventHandler);
* *

If you pass in an event name (or names) and no handler method, all handlers are * removed for those events:

* *
obj.off("event1Name event2Name");
* *

If you pass in no arguments, all event handlers are removed for all events * dispatched by the object:

* *
obj.off();
* *

* The method also supports an alternate syntax, in which the first parameter is an object that * is a hash map of event names and handler functions and the second parameter (optional) is * the context for this in each handler: *

*
         * obj.off(
         *    {
  *       eventName1: event1Handler,
  *       eventName2: event2Handler
  *    });
         * 
* * @param {String} type (Optional) The string identifying the type of event. You can * use a space to specify multiple events, as in "accessAllowed accessDenied * accessDialogClosed". If you pass in no type value (or other arguments), * all event handlers are removed for the object. * @param {Function} handler (Optional) The event handler function to remove. The handler * must be the same function object as was passed into on(). Be careful with * helpers like bind() that return a new function when called. If you pass in * no handler, all event handlers are removed for the specified event * type. * @param {Object} context (Optional) If you specify a context, the event handler * is removed for all specified events and handlers that use the specified context. (The * context must match the context passed into on().) * * @returns {Object} The object that dispatched the event. * * @memberOf EventDispatcher * @method #off * @see on() * @see once() * @see Events */ self.off = function(eventNames, handlerOrContext, context) { if (typeof eventNames === 'string') { if (handlerOrContext && util.isFunction(handlerOrContext)) { innerEventing.removeListeners(eventNames.split(' '), handlerOrContext, context); } else { innerEventing.removeAllListenersNamed(eventNames.split(' ')); } } else if (!eventNames) { innerEventing.removeAllListeners(); } else { for (var name in eventNames) { if (eventNames.hasOwnProperty(name)) { innerEventing.removeListeners([name], eventNames[name], handlerOrContext); } } } return this; }; /** * Adds an event handler function for one or more events. Once the handler is called, * the specified handler method is removed as a handler for this event. (When you use * the on() method to add an event handler, the handler is not * removed when it is called.) The once() method is the equivilent of * calling the on() * method and calling off() the first time the handler is invoked. * *

* The following code adds a one-time event handler for the accessAllowed event: *

* *
         * obj.once("eventName", function (event) {
  *    // This is the event handler.
  * });
         * 
* *

If you pass in multiple event names and a handler method, the handler is registered * for each of those events:

* *
obj.once("eventName1 eventName2"
         *          function (event) {
  *              // This is the event handler.
  *          });
         * 
* *

You can also pass in a third context parameter (which is optional) to define * the value of * this in the handler method:

* *
obj.once("eventName",
         *          function (event) {
  *              // This is the event handler.
  *          },
         *          obj);
         * 
* *

* The method also supports an alternate syntax, in which the first parameter is an object that * is a hash map of event names and handler functions and the second parameter (optional) is the * context for this in each handler: *

*
         * obj.once(
         *    {
  *       eventName1: function (event) {
  *                  // This is the event handler for eventName1.
  *           },
  *       eventName2:  function (event) {
  *                  // This is the event handler for eventName1.
  *           }
  *    },
         *    obj);
         * 
* * @param {String} type The string identifying the type of event. You can specify multiple * event names in this string, separating them with a space. The event handler will process * the first occurence of the events. After the first event, the handler is removed (for * all specified events). * @param {Function} handler The handler function to process the event. This function takes * the event object as a parameter. * @param {Object} context (Optional) Defines the value of this in the event * handler function. * * @returns {Object} The object that dispatched the event. * * @memberOf EventDispatcher * @method #once * @see on() * @see off() * @see Events */ self.once = function(eventNames, handler, context) { var handleThisOnce = function() { self.off(eventNames, handleThisOnce, context); handler.apply(context, arguments); }; handleThisOnce.originalHandler = handler; self.on(eventNames, handleThisOnce, context); return this; }; // Execute any listeners bound to the +event+ Event. // // Each handler will be executed async. On completion the defaultAction // handler will be executed with the args. // // @param [Event] event // An Event object. // // @param [Function, Null, Undefined] defaultAction // An optional function to execute after every other handler. This will execute even // if there are listeners bound to this event. +defaultAction+ will be passed // args as a normal handler would. // // @return this // self.dispatchEvent = function(event, defaultAction) { if (!event.type) { logging.error('OTHelpers.Eventing.dispatchEvent: Event has no type'); logging.error(event); throw new Error('OTHelpers.Eventing.dispatchEvent: Event has no type'); } if (!event.target) { event.target = this; } innerEventing.dispatchEvent(event, defaultAction); return this; }; // Execute each handler for the event called +name+. // // Each handler will be executed async, and any exceptions that they throw will // be caught and logged // // How to pass these? // * defaultAction // // @example // foo.on('bar', function(name, message) { // alert("Hello " + name + ": " + message); // }); // // foo.trigger('OpenTok', 'asdf'); // -> Hello OpenTok: asdf // // // @param [String] eventName // The name of this event. // // @param [Array] arguments // Any additional arguments beyond +eventName+ will be passed to the handlers. // // @return this // self.trigger = function(/* eventName [, arg0, arg1, ..., argN ] */) { innerEventing.trigger.apply(innerEventing, arguments); return this; }; // Alias of trigger for easier node compatibility self.emit = self.trigger; /** * Deprecated; use on() or once() instead. *

* This method registers a method as an event listener for a specific event. *

* *

* If a handler is not registered for an event, the event is ignored locally. If the * event listener function does not exist, the event is ignored locally. *

*

* Throws an exception if the listener name is invalid. *

* * @param {String} type The string identifying the type of event. * * @param {Function} listener The function to be invoked when the object dispatches the event. * * @param {Object} context (Optional) Defines the value of this in the event * handler function. * * @memberOf EventDispatcher * @method #addEventListener * @see on() * @see once() * @see Events */ // See 'on' for usage. // @depreciated will become a private helper function in the future. self.addEventListener = function(eventName, handler, context) { logging.warn('The addEventListener() method is deprecated. Use on() or once() instead.'); return self.on(eventName, handler, context); }; /** * Deprecated; use off() instead. *

* Removes an event listener for a specific event. *

* *

* Throws an exception if the listener name is invalid. *

* * @param {String} type The string identifying the type of event. * * @param {Function} listener The event listener function to remove. * * @param {Object} context (Optional) If you specify a context, the event * handler is removed for all specified events and event listeners that use the specified context. (The context must match the context passed into * addEventListener().) * * @memberOf EventDispatcher * @method #removeEventListener * @see off() * @see Events */ // See 'off' for usage. // @depreciated will become a private helper function in the future. self.removeEventListener = function(eventName, handler, context) { logging.warn('The removeEventListener() method is deprecated. Use off() instead.'); return self.off(eventName, handler, context); }; // We expose the inner eventing for testing purposes. if (!self.__testOnly) { self.__testOnly = {}; } self.__testOnly.innerEventing = innerEventing; return self; }; },{"../logging":29,"../util":34,"./eventing/browser":8,"./eventing/node":10}],8:[function(require,module,exports){ 'use strict'; var env = require('../../env'); var callbacks = require('../../callbacks'); if(env.name !== 'Node') { module.exports = function browserEventing(self, syncronous) { var api = { events: {} }; // Call the defaultAction, passing args function executeDefaultAction(defaultAction, args) { if (!defaultAction) return; defaultAction.apply(null, args.slice()); } // Execute each handler in +listeners+ with +args+. // // Each handler will be executed async. On completion the defaultAction // handler will be executed with the args. // // @param [Array] listeners // An array of functions to execute. Each will be passed args. // // @param [Array] args // An array of arguments to execute each function in +listeners+ with. // // @param [String] name // The name of this event. // // @param [Function, Null, Undefined] defaultAction // An optional function to execute after every other handler. This will execute even // if +listeners+ is empty. +defaultAction+ will be passed args as a normal // handler would. // // @return Undefined // function executeListenersAsyncronously(name, args, defaultAction) { var listeners = api.events[name]; if (!listeners || listeners.length === 0) return; var listenerAcks = listeners.length; listeners.forEach(function(listener) { // , index function filterHandlers(_listener) { return _listener.handler === listener.handler; } // We run this asynchronously so that it doesn't interfere with execution if an // error happens callbacks.callAsync(function() { try { // have to check if the listener has not been removed if (api.events[name] && api.events[name].some(filterHandlers)) { (listener.closure || listener.handler).apply(listener.context || null, args); } } finally { listenerAcks--; if (listenerAcks === 0) { executeDefaultAction(defaultAction, args); } } }); }); } // This is identical to executeListenersAsyncronously except that handlers will // be executed syncronously. // // On completion the defaultAction handler will be executed with the args. // // @param [Array] listeners // An array of functions to execute. Each will be passed args. // // @param [Array] args // An array of arguments to execute each function in +listeners+ with. // // @param [String] name // The name of this event. // // @param [Function, Null, Undefined] defaultAction // An optional function to execute after every other handler. This will execute even // if +listeners+ is empty. +defaultAction+ will be passed args as a normal // handler would. // // @return Undefined // function executeListenersSyncronously(name, args) { // defaultAction is not used var listeners = api.events[name]; if (!listeners || listeners.length === 0) return; listeners.forEach(function(listener) { // index (listener.closure || listener.handler).apply(listener.context || null, args); }); } var executeListeners = syncronous === true ? executeListenersSyncronously : executeListenersAsyncronously; api.addListeners = function (eventNames, handler, context, closure) { var listener = {handler: handler}; if (context) listener.context = context; if (closure) listener.closure = closure; eventNames.forEach(function(name) { if (!api.events[name]) api.events[name] = []; api.events[name].push(listener); var addedListener = name + ':added'; if (api.events[addedListener]) { executeListeners(addedListener, [api.events[name].length]); } }); }; api.removeListeners = function(eventNames, handler, context) { function filterListeners(listener) { var isCorrectHandler = ( listener.handler.originalHandler === handler || listener.handler === handler ); return !(isCorrectHandler && listener.context === context); } eventNames.forEach(function(name) { if (api.events[name]) { api.events[name] = api.events[name].filter(filterListeners); if (api.events[name].length === 0) delete api.events[name]; var removedListener = name + ':removed'; if (api.events[ removedListener]) { executeListeners(removedListener, [api.events[name] ? api.events[name].length : 0]); } } }); }; api.removeAllListenersNamed = function (eventNames) { eventNames.forEach(function(name) { if (api.events[name]) { delete api.events[name]; } }); }; api.removeAllListeners = function () { api.events = {}; }; api.dispatchEvent = function(event, defaultAction) { if (!api.events[event.type] || api.events[event.type].length === 0) { executeDefaultAction(defaultAction, [event]); return; } executeListeners(event.type, [event], defaultAction); }; api.trigger = function(/* eventName [, arg1, arg2, ...argN] */) { var args = Array.prototype.slice.call(arguments); var eventName = args.shift(); if (!api.events[eventName] || api.events[eventName].length === 0) { return; } executeListeners(eventName, args); }; return api; }; } },{"../../callbacks":12,"../../env":25}],9:[function(require,module,exports){ 'use strict'; var logging = require('../../logging'); module.exports = function Event() { return function (type, cancelable) { this.type = type; this.cancelable = cancelable !== undefined ? cancelable : true; var _defaultPrevented = false; this.preventDefault = function() { if (this.cancelable) { _defaultPrevented = true; } else { logging.warn('Event.preventDefault :: Trying to preventDefault ' + 'on an Event that isn\'t cancelable'); } }; this.isDefaultPrevented = function() { return _defaultPrevented; }; }; }; },{"../../logging":29}],10:[function(require,module,exports){ 'use strict'; var env = require('../../env'); if (env.name === 'Node') { var EventEmitter = require('events').EventEmitter, nodeUtil = require('util'); // container for the EventEmitter behaviour. This prevents tight coupling // caused by accidentally bleeding implementation details and API into whatever // objects nodeEventing is applied to. var NodeEventable = function NodeEventable() { EventEmitter.call(this); this.events = {}; }; nodeUtil.inherits(NodeEventable, EventEmitter); module.exports = function nodeEventing(/* self */) { var api = new NodeEventable(); api.addListeners = function (eventNames, handler, context, closure) { var listener = {handler: handler}; if (context) listener.context = context; if (closure) listener.closure = closure; eventNames.forEach(function(name) { if (!api.events[name]) api.events[name] = []; api.events[name].push(listener); api.on(name, handler); var addedListener = name + ':added'; if (api.events[addedListener]) { api.emit(addedListener, api.events[name].length); } }); }; api.removeAllListenersNamed = function (eventNames) { var _eventNames = eventNames.split(' '); api.removeAllListeners(_eventNames); _eventNames.forEach(function(name) { if (api.events[name]) delete api.events[name]; }); }; api.removeListeners = function (eventNames, handler, closure) { function filterHandlers(listener) { return !(listener.handler === handler && listener.closure === closure); } eventNames.split(' ').forEach(function(name) { if (api.events[name]) { api.off(name, handler); api.events[name] = api.events[name].filter(filterHandlers); if (api.events[name].length === 0) delete api.events[name]; var removedListener = name + ':removed'; if (api.events[removedListener]) { api.emit(removedListener, api.events[name] ? api.events[name].length : 0); } } }); }; api.removeAllListeners = function () { api.events = {}; api.removeAllListeners(); }; api.dispatchEvent = function(event, defaultAction) { this.emit(event.type, event); if (defaultAction) { defaultAction.call(null, event); } }; api.trigger = api.emit.bind(api); return api; }; } else { module.exports = undefined; } },{"../../env":25,"events":72,"util":77}],11:[function(require,module,exports){ 'use strict'; var util = require('../util'); module.exports = function statable( self, possibleStates, initialState, stateChanged, stateChangedFailed ) { var previousState, currentState = self.currentState = initialState; var setState = function(state) { if (currentState !== state) { if (possibleStates.indexOf(state) === -1) { if (stateChangedFailed && util.isFunction(stateChangedFailed)) { stateChangedFailed('invalidState', state); } return; } self.previousState = previousState = currentState; self.currentState = currentState = state; if (stateChanged && util.isFunction(stateChanged)) stateChanged(state, previousState); } }; // Returns a number of states and returns true if the current state // is any of them. // // @example // if (this.is('connecting', 'connected')) { // // do some stuff // } // self.is = function (/* state0:String, state1:String, ..., stateN:String */) { return Array.prototype.indexOf.call(arguments, currentState) !== -1; }; // Returns a number of states and returns true if the current state // is none of them. // // @example // if (this.isNot('connecting', 'connected')) { // // do some stuff // } // self.isNot = function (/* state0:String, state1:String, ..., stateN:String */) { return Array.prototype.indexOf.call(arguments, currentState) === -1; }; return setState; }; },{"../util":34}],12:[function(require,module,exports){ 'use strict'; var makeEverythingAttachToOTHelpers = require('./makeEverythingAttachToOTHelpers'); var callbacks = {}; module.exports = callbacks; // Calls the function +fn+ asynchronously with the current execution. // This is most commonly used to execute something straight after // the current function. // // Any arguments in addition to +fn+ will be passed to +fn+ when it's // called. // // You would use this inplace of setTimeout(fn, 0) type constructs. callAsync // is preferable as it executes in a much more predictable time global, // unlike setTimeout which could execute anywhere from 2ms to several thousand // depending on the browser/context. // // It does this using global.postMessage, although if postMessage won't // work it will fallback to setTimeout. // callbacks.callAsync = function (/* fn, [arg1, arg2, ..., argN] */) { var args = Array.prototype.slice.call(arguments); var fn = args.shift(); setTimeout(function() { fn.apply(null, args); }, 0); }; // Wraps +handler+ in a function that will execute it asynchronously // so that it doesn't interfere with it's exceution context if it raises // an exception. callbacks.createAsyncHandler = function(handler) { return function() { var args = Array.prototype.slice.call(arguments); callbacks.callAsync(function() { handler.apply(null, args); }); }; }; makeEverythingAttachToOTHelpers(callbacks); },{"./makeEverythingAttachToOTHelpers":31}],13:[function(require,module,exports){ 'use strict'; var logging = require('./logging'); var makeEverythingAttachToOTHelpers = require('./makeEverythingAttachToOTHelpers'); var util = require('./util'); var capabilities = {}; module.exports = capabilities; var capabilityRegistry = {}; var memoriseCapabilityTest; // Registers a new capability type and a function that will indicate // whether this client has that capability. // // OTHelpers.registerCapability('bundle', function() { // return OTHelpers.hasCapabilities('webrtc') && // (OTHelpers.env.name === 'Chrome' || TBPlugin.isInstalled()); // }); // capabilities.registerCapability = function(name, callback) { var _name = name.toLowerCase(); if (capabilityRegistry.hasOwnProperty(_name)) { logging.error('Attempted to register', name, 'capability more than once'); return; } if (!util.isFunction(callback)) { logging.error('Attempted to register', name, 'capability with a callback that isn\' a function'); return; } memoriseCapabilityTest(_name, callback); }; // Wrap up a capability test in a function that memorises the // result. memoriseCapabilityTest = function (name, callback) { capabilityRegistry[name] = function() { var result = callback(); capabilityRegistry[name] = function() { return result; }; return result; }; }; var testCapability = function (name) { return capabilityRegistry[name](); }; /* test-code */ capabilities.__testOnly = {}; capabilities.__testOnly.disableCapabilityMemorisation = false; var rawCapabilityRegistry = {}, defaultMemoriseCapabilityTest = memoriseCapabilityTest; // Intercept the memorise call and store the raw callbacks in test mode memoriseCapabilityTest = function (name, callback) { rawCapabilityRegistry[name.toLowerCase()] = callback; return defaultMemoriseCapabilityTest(name, callback); }; // Override this call in test mode testCapability = function (name) { var cap; if (capabilities.__testOnly.disableCapabilityMemorisation === true) { cap = rawCapabilityRegistry[name]; } else { cap = capabilityRegistry[name]; } return cap(); }; capabilities.__testOnly.resetCapabilities = function() { rawCapabilityRegistry = {}; capabilityRegistry = {}; }; capabilities.__testOnly.unmemoriseCapability = function(name) { memoriseCapabilityTest(name, rawCapabilityRegistry[name]); }; capabilities.__testOnly.removeCapabilities = function() { var names = Array.prototype.slice.call(arguments), num = names.length; for (var i = 0; i < num; ++i) { delete rawCapabilityRegistry[names[i]]; delete capabilityRegistry[names[i]]; } }; /* end-test-code */ // Returns true if all of the capability names passed in // exist and are met. // // OTHelpers.hasCapabilities('bundle', 'rtcpMux') // capabilities.hasCapabilities = function(/* capability1, capability2, ..., capabilityN */) { var capNames = Array.prototype.slice.call(arguments), name; for (var i = 0; i < capNames.length; ++i) { name = capNames[i].toLowerCase(); if (!capabilityRegistry.hasOwnProperty(name)) { logging.error('hasCapabilities was called with an unknown capability: ' + name); return false; } else if (testCapability(name) === false) { return false; } } return true; }; makeEverythingAttachToOTHelpers(capabilities); },{"./logging":29,"./makeEverythingAttachToOTHelpers":31,"./util":34}],14:[function(require,module,exports){ 'use strict'; var makeEverythingAttachToOTHelpers = require('./makeEverythingAttachToOTHelpers'); var casting = {}; module.exports = casting; casting.castToBoolean = function(value, defaultValue) { if (value === undefined) { return defaultValue; } return value === 'true' || value === true; }; casting.roundFloat = function(value, places) { return Number(value.toFixed(places)); }; makeEverythingAttachToOTHelpers(casting); },{"./makeEverythingAttachToOTHelpers":31}],15:[function(require,module,exports){ 'use strict'; var eventing = require('./behaviours/eventing'); var logging = require('./logging'); var util = require('./util'); module.exports = function Collection(idField) { var _models = [], _byId = {}, _idField = idField || 'id'; eventing(this, true); var modelProperty = function(model, property) { if (util.isFunction(model[property])) { return model[property](); } else { return model[property]; } }; var onModelUpdate = function onModelUpdate(event) { this.trigger('update', event); this.trigger('update:'+event.target.id, event); }.bind(this), onModelDestroy = function onModelDestroyed(event) { this.remove(event.target, event.reason); }.bind(this); this.reset = function() { // Stop listening on the models, they are no longer our problem _models.forEach(function(model) { model.off('updated', onModelUpdate, this); model.off('destroyed', onModelDestroy, this); }, this); _models = []; _byId = {}; }; this.destroy = function(reason) { _models.forEach(function(model) { if(model && typeof model.destroy === 'function') { model.destroy(reason, true); } }); this.reset(); this.off(); }; this.get = function(id) { return id && _byId[id] !== void 0 ? _models[_byId[id]] : void 0; }; this.has = function(id) { return id && _byId[id] !== void 0; }; this.toString = function() { return _models.toString(); }; // Return only models filtered by either a dict of properties // or a filter function. // // @example Return all publishers with a streamId of 1 // OT.publishers.where({streamId: 1}) // // @example The same thing but filtering using a filter function // OT.publishers.where(function(publisher) { // return publisher.stream.id === 4; // }); // // @example The same thing but filtering using a filter function // executed with a specific this // OT.publishers.where(function(publisher) { // return publisher.stream.id === 4; // }, self); // this.where = function(attrsOrFilterFn, context) { if (util.isFunction(attrsOrFilterFn)) { return _models.filter(attrsOrFilterFn, context); } return _models.filter(function(model) { for (var key in attrsOrFilterFn) { if(!attrsOrFilterFn.hasOwnProperty(key)) { continue; } if (modelProperty(model, key) !== attrsOrFilterFn[key]) return false; } return true; }); }; // Similar to where in behaviour, except that it only returns // the first match. this.find = function(attrsOrFilterFn, context) { var filterFn; if (util.isFunction(attrsOrFilterFn)) { filterFn = attrsOrFilterFn; } else { filterFn = function(model) { for (var key in attrsOrFilterFn) { if(!attrsOrFilterFn.hasOwnProperty(key)) { continue; } if (modelProperty(model, key) !== attrsOrFilterFn[key]) return false; } return true; }; } filterFn = filterFn.bind(context); for (var i=0; i<_models.length; ++i) { if (filterFn(_models[i]) === true) return _models[i]; } return null; }; this.forEach = function(fn, context) { _models.forEach(fn, context); return this; }; this.add = function(model) { var id = modelProperty(model, _idField); if (this.has(id)) { logging.warn('Model ' + id + ' is already in the collection', _models); return this; } _byId[id] = _models.push(model) - 1; model.on('updated', onModelUpdate, this); model.on('destroyed', onModelDestroy, this); this.trigger('add', model); this.trigger('add:'+id, model); return this; }; this.remove = function(model, reason) { var id = modelProperty(model, _idField); _models.splice(_byId[id], 1); // Shuffle everyone down one for (var i=_byId[id]; i<_models.length; ++i) { _byId[_models[i][_idField]] = i; } delete _byId[id]; model.off('updated', onModelUpdate, this); model.off('destroyed', onModelDestroy, this); this.trigger('remove', model, reason); this.trigger('remove:'+id, model, reason); return this; }; // Retrigger the add event behaviour for each model. You can also // select a subset of models to trigger using the same arguments // as the #where method. this._triggerAddEvents = function() { this.where.apply(this, arguments).forEach(function(model) { this.trigger('add', model); this.trigger('add:' + modelProperty(model, _idField), model); }, this); }; this.length = function() { return _models.length; }; }; },{"./behaviours/eventing":7,"./logging":29,"./util":34}],16:[function(require,module,exports){ 'use strict'; var makeEverythingAttachToOTHelpers = require('./makeEverythingAttachToOTHelpers'); var cookies = {}; module.exports = cookies; cookies.setCookie = function(key, value) { try { localStorage.setItem(key, value); } catch (err) { // Store in browser cookie var date = new Date(); date.setTime(date.getTime() + (365 * 24 * 60 * 60 * 1000)); var expires = '; expires=' + date.toGMTString(); document.cookie = key + '=' + value + expires + '; path=/'; } }; cookies.getCookie = function(key) { var value; try { value = localStorage.getItem(key); return value; } catch (err) { // Check browser cookies var nameEQ = key + '='; var ca = document.cookie.split(';'); for(var i=0;i < ca.length;i++) { var c = ca[i]; while (c.charAt(0) === ' ') { c = c.substring(1,c.length); } if (c.indexOf(nameEQ) === 0) { value = c.substring(nameEQ.length,c.length); } } if (value) { return value; } } return null; }; makeEverythingAttachToOTHelpers(cookies); },{"./makeEverythingAttachToOTHelpers":31}],17:[function(require,module,exports){ 'use strict'; var $ = require('./elementCollection/shorthandSelector'); var makeEverythingAttachToOTHelpers = require('./makeEverythingAttachToOTHelpers'); var domExtras = {}; module.exports = domExtras; domExtras.isElementNode = function(node) { return node && typeof node === 'object' && node.nodeType === 1; }; domExtras.createElement = function(nodeName, attributes, children, doc) { var element = (doc || document).createElement(nodeName); if (attributes) { for (var name in attributes) { if (typeof(attributes[name]) === 'object') { if (!element[name]) element[name] = {}; var subAttrs = attributes[name]; for (var n in subAttrs) { element[name][n] = subAttrs[n]; } } else if (name === 'className') { element.className = attributes[name]; } else { element.setAttribute(name, attributes[name]); } } } var setChildren = function(child) { if(typeof child === 'string') { element.innerHTML = element.innerHTML + child; } else { element.appendChild(child); } }; if (Array.isArray(children)) { children.forEach(setChildren); } else if(children) { setChildren(children); } return element; }; domExtras.createButton = function(innerHTML, attributes, events) { var button = domExtras.createElement('button', attributes, innerHTML); if (events) { for (var name in events) { if (events.hasOwnProperty(name)) { $(button).on(name, events[name]); } } button._boundEvents = events; } return button; }; makeEverythingAttachToOTHelpers(domExtras); },{"./elementCollection/shorthandSelector":24,"./makeEverythingAttachToOTHelpers":31}],18:[function(require,module,exports){ (function (global){ 'use strict'; var makeEverythingAttachToOTHelpers = require('./makeEverythingAttachToOTHelpers'); var domLoad = {}; module.exports = domLoad; var _domReady = typeof(document) === 'undefined' || document.readyState === 'complete' || (document.readyState === 'interactive' && document.body), _loadCallbacks = [], _unloadCallbacks = [], _domUnloaded = false, onDomUnload = function() { _domUnloaded = true; _unloadCallbacks.forEach(function(listener) { listener[0].call(listener[1]); }); _unloadCallbacks = []; }, onDomReady = function() { _domReady = true; if (typeof(document) !== 'undefined') { document.removeEventListener('DOMContentLoaded', onDomReady, false); global.removeEventListener('load', onDomReady, false); // This is making an assumption about there being only one 'global' // that we care about. var globalonunload = global.onunload; global.onunload = function() { if (typeof globalonunload === 'function') { globalonunload.apply(undefined, arguments); } onDomUnload(); } } // @TODO consider how to trigger/handle clean up Node. This is // obviously not the Object to do it in, as there is no DOM in // Node. But this is where the equivilant browser code is so // it's a good place to leave a todo. _loadCallbacks.forEach(function(listener) { listener[0].call(listener[1]); }); _loadCallbacks = []; }; domLoad.isReady = function() { return !_domUnloaded && _domReady; }; domLoad.onDOMLoad = function(cb, context) { if (domLoad.isReady()) { cb.call(context); return; } _loadCallbacks.push([cb, context]); }; domLoad.onDOMUnload = function(cb, context) { if (this.isDOMUnloaded()) { cb.call(context); return; } _unloadCallbacks.push([cb, context]); }; domLoad.isDOMUnloaded = function() { return _domUnloaded; }; if (_domReady) { onDomReady(); } else if(typeof(document) !== 'undefined') { document.addEventListener('DOMContentLoaded', onDomReady, false); // fallback global.addEventListener('load', onDomReady, false ); } makeEverythingAttachToOTHelpers(domLoad); }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) },{"./makeEverythingAttachToOTHelpers":31}],19:[function(require,module,exports){ 'use strict'; var util = require('../../util'); var specialDomProperties = { 'for': 'htmlFor', 'class': 'className' }; module.exports = function(ElementCollection) { // Gets or sets the attribute called +name+ for the first element in the collection ElementCollection.prototype.attr = function (name, value) { if (util.isObject(name)) { var actualName; for (var key in name) { actualName = specialDomProperties[key] || key; this.first.setAttribute(actualName, name[key]); } } else if (value === void 0) { return this.first.getAttribute(specialDomProperties[name] || name); } else { this.first.setAttribute(specialDomProperties[name] || name, value); } return this; }; // Removes an attribute called +name+ for the every element in the collection. ElementCollection.prototype.removeAttr = function (name) { var actualName = specialDomProperties[name] || name; this.forEach(function(element) { element.removeAttribute(actualName); }); return this; }; // Gets, and optionally sets, the html body of the first element // in the collection. If the +html+ is provided then the first // element's html body will be replaced with it. // ElementCollection.prototype.html = function (html) { if (html !== void 0) { this.first.innerHTML = html; } return this.first.innerHTML; }; // Centers +element+ within the global. You can pass through the width and height // if you know it, if you don't they will be calculated for you. ElementCollection.prototype.center = function (width, height) { var $element; this.forEach(function(element) { $element = new ElementCollection(element); if (!width) width = parseInt($element.width(), 10); if (!height) height = parseInt($element.height(), 10); var marginLeft = -0.5 * width + 'px'; var marginTop = -0.5 * height + 'px'; $element.css('margin', marginTop + ' 0 0 ' + marginLeft) .addClass('OT_centered'); }); return this; }; // @remove // Centers +element+ within the global. You can pass through the width and height // if you know it, if you don't they will be calculated for you. ElementCollection._attachToOTHelpers.centerElement = function(element, width, height) { return new ElementCollection(element).center(width, height); }; /** * Methods to calculate element widths and heights. */ var _width = function(element) { if (element.offsetWidth > 0) { return element.offsetWidth + 'px'; } return new ElementCollection(element).css('width'); }, _height = function(element) { if (element.offsetHeight > 0) { return element.offsetHeight + 'px'; } return new ElementCollection(element).css('height'); }; ElementCollection.prototype.width = function (newWidth) { if (newWidth) { this.css('width', newWidth); return this; } else { if (this.isDisplayNone()) { return this.makeVisibleAndYield(function(element) { return _width(element); })[0]; } else { return _width(this.get(0)); } } }; // @remove ElementCollection._attachToOTHelpers.width = function(element, newWidth) { var ret = new ElementCollection(element).width(newWidth); return newWidth ? ElementCollection._attachToOTHelpers : ret; }; ElementCollection.prototype.height = function (newHeight) { if (newHeight) { this.css('height', newHeight); return this; } else { if (this.isDisplayNone()) { // We can't get the height, probably since the element is hidden. return this.makeVisibleAndYield(function(element) { return _height(element); })[0]; } else { return _height(this.get(0)); } } }; // @remove ElementCollection._attachToOTHelpers.height = function(element, newHeight) { var ret = new ElementCollection(element).height(newHeight); return newHeight ? ElementCollection._attachToOTHelpers : ret; }; }; },{"../../util":34}],20:[function(require,module,exports){ 'use strict'; var capabilities = require('../../capabilities'); function isClassListSupported() { return (typeof document !== 'undefined') && ('classList' in document.createElement('a')); } var classListSupported = isClassListSupported(); // Returns true if the client supports element.classList capabilities.registerCapability('classList', isClassListSupported); function hasClass(element, className) { if (!className) { return false; } if (classListSupported) { return element.classList.contains(className); } return element.className.indexOf(className) > -1; } function toggleClasses(element, classNames) { if (!classNames || classNames.length === 0) return; // Only bother targeting Element nodes, ignore Text Nodes, CDATA, etc if (element.nodeType !== 1) { return; } var numClasses = classNames.length, i = 0; if (classListSupported) { for (; i